/**
 * 从 schema 文件中的 JSDoc 注释自动生成 SQL COMMENT 语句
 * 
 * 使用方法：
 * tsx libs/db/scripts/generate-comments-from-schema.ts
 */

import { readFileSync, writeFileSync, readdirSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

interface FieldComment {
  table: string;
  field: string;
  comment: string;
}

interface TableComment {
  table: string;
  comment: string;
}

/**
 * 解析 schema 文件，提取字段注释
 */
function parseSchemaFile(filePath: string): { fields: FieldComment[]; table?: TableComment } {
  const content = readFileSync(filePath, 'utf-8');
  const fields: FieldComment[] = [];
  let tableComment: TableComment | undefined;

  // 提取表名
  const tableMatch = content.match(/pgTable\s*\(\s*['"]([^'"]+)['"]/);
  if (!tableMatch) return { fields };

  const tableName = tableMatch[1];

  // 提取表注释
  const tableCommentMatch = content.match(/\/\*\*\s*\n\s*\*\s*(.+?)\s*\n\s*\*\//s);
  if (tableCommentMatch) {
    tableComment = {
      table: tableName,
      comment: tableCommentMatch[1].trim(),
    };
  }

  // 提取字段注释
  // 匹配模式：/** 注释 */ field: type('field_name')
  // 使用逐行解析，更准确
  const lines = content.split('\n');
  
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    
    // 检查是否是字段注释行（单行注释）
    const commentMatch = line.match(/^\s*\/\*\*\s*(.+?)\s*\*\/\s*$/);
    if (!commentMatch) continue;
    
    // 获取注释内容
    const comment = commentMatch[1].trim();
    
    // 跳过表注释（包含"系统-"或"表"）
    if (comment.includes('系统-') || (comment.includes('表') && !comment.includes('主键') && !comment.includes('外键'))) continue;
    
    // 查找下一行的字段定义（可能需要跳过空行）
    let nextLineIndex = i + 1;
    while (nextLineIndex < lines.length && lines[nextLineIndex].trim() === '') {
      nextLineIndex++;
    }
    if (nextLineIndex >= lines.length) continue;
    
    const nextLine = lines[nextLineIndex];
    
    // 匹配字段定义：fieldName: type('field_name') 或 fieldName: type('field_name', {...})
    const fieldMatch = nextLine.match(/^\s*(\w+):\s*\w+\(['"]([^'"]+)['"]/);
    if (!fieldMatch) continue;
    
    const fieldName = fieldMatch[2]; // 使用数据库字段名（第二个参数）
    
    if (comment && fieldName) {
      fields.push({
        table: tableName,
        field: fieldName,
        comment,
      });
    }
  }

  return { fields, table: tableComment };
}

/**
 * 生成 SQL COMMENT 语句
 */
function generateCommentSQL(fields: FieldComment[], tables: TableComment[]): string {
  const lines: string[] = [];

  lines.push('-- 自动生成的字段注释 SQL');
  lines.push('-- 从 schema 文件中的 JSDoc 注释生成');
  lines.push('-- 执行方式：psql -U your_user -d your_database -f libs/db/scripts/add-column-comments.sql');
  lines.push('');
  lines.push('-- ============================================');
  lines.push('-- 表注释');
  lines.push('-- ============================================');
  lines.push('');

  for (const table of tables) {
    lines.push(`COMMENT ON TABLE "${table.table}" IS '${table.comment}';`);
  }

  lines.push('');
  lines.push('-- ============================================');
  lines.push('-- 字段注释');
  lines.push('-- ============================================');
  lines.push('');

  // 按表分组
  const fieldsByTable = new Map<string, FieldComment[]>();
  for (const field of fields) {
    if (!fieldsByTable.has(field.table)) {
      fieldsByTable.set(field.table, []);
    }
    fieldsByTable.get(field.table)!.push(field);
  }

  // 生成注释
  for (const [tableName, tableFields] of fieldsByTable.entries()) {
    lines.push(`-- ${tableName} 表字段注释`);
    for (const field of tableFields) {
      lines.push(`COMMENT ON COLUMN "${field.table}"."${field.field}" IS '${field.comment}';`);
    }
    lines.push('');
  }

  return lines.join('\n');
}

/**
 * 将注释添加到迁移文件中
 */
function addCommentsToMigration(migrationDir: string, fields: FieldComment[], tables: TableComment[]): void {
  // 查找最新的迁移文件
  const migrationFiles = readdirSync(migrationDir)
    .filter(file => file.endsWith('.sql') && file.match(/^\d{4}_/))
    .sort()
    .reverse();

  if (migrationFiles.length === 0) {
    console.log('⚠️  未找到迁移文件，跳过注释添加');
    return;
  }

  const latestMigration = migrationFiles[0];
  const migrationPath = join(migrationDir, latestMigration);
  let migrationContent = readFileSync(migrationPath, 'utf-8');

  // 检查是否已经包含注释
  if (migrationContent.includes('COMMENT ON')) {
    console.log(`⚠️  迁移文件 ${latestMigration} 已包含注释，跳过`);
    return;
  }

  // 生成注释 SQL
  const commentSQL = generateCommentSQL(fields, tables);

  // 在文件末尾添加注释
  migrationContent += '\n' + commentSQL;

  // 写入文件
  writeFileSync(migrationPath, migrationContent, 'utf-8');

  console.log(`✅ 已将注释添加到迁移文件: ${latestMigration}`);
}

/**
 * 主函数
 */
function main() {
  const schemaDir = join(__dirname, '../src/schema');
  const migrationDir = join(__dirname, '../drizzle');
  const outputFile = join(__dirname, 'add-column-comments.sql');

  // 查找所有 schema 文件
  const schemaFiles = readdirSync(schemaDir)
    .filter(file => file.endsWith('.schema.ts'));

  const allFields: FieldComment[] = [];
  const allTables: TableComment[] = [];

  // 解析所有 schema 文件
  for (const file of schemaFiles) {
    const filePath = join(schemaDir, file);
    const { fields, table } = parseSchemaFile(filePath);

    allFields.push(...fields);
    if (table) {
      allTables.push(table);
    }
  }

  // 生成独立的 SQL 文件
  const sql = generateCommentSQL(allFields, allTables);
  writeFileSync(outputFile, sql, 'utf-8');

  // 尝试添加到迁移文件
  try {
    addCommentsToMigration(migrationDir, allFields, allTables);
  } catch (error) {
    console.log('⚠️  无法添加到迁移文件，但已生成独立 SQL 文件');
  }

  console.log(`✅ 已生成注释 SQL 文件: ${outputFile}`);
  console.log(`📊 统计:`);
  console.log(`   - 表数量: ${allTables.length}`);
  console.log(`   - 字段数量: ${allFields.length}`);
}

main();

